home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / Snippets / Interapplication Communication / AE Interaction Sample / reciever.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-08  |  14.1 KB  |  406 lines  |  [TEXT/MPS ]

  1. /* Sender and Reciever are simple AppleEvent programs that demonstrate */
  2. /* all the permutations of interaction levels for sending */
  3. /* and recieving APpleEvents. */
  4. /* Have fun with them. */
  5. /* C.K. Haun */
  6. /* Apple DTS */
  7. /* this recieves the simple event */
  8. #include <Types.h>
  9. #include <memory.h>
  10. #include <Packages.h>
  11. #include <Errors.h>
  12. #include <quickdraw.h>
  13. #include <fonts.h>
  14. #include <dialogs.h>
  15. #include <windows.h>
  16. #include <menus.h>
  17. #include <events.h>
  18. #include <OSEvents.h>
  19. #include <Desk.h>
  20. #include <diskinit.h>
  21. #include <OSUtils.h>
  22. #include <resources.h>
  23. #include <toolutils.h>
  24. #include <AppleEvents.h>
  25. #include <EPPC.h>
  26. #include <GestaltEqu.h>
  27. #include <PPCToolbox.h> 
  28. #include <Processes.h>
  29. void DoDiskEvents(long dinfo);                              /* hi word is error code, lo word is drive number */
  30.  
  31. void DrawMain(WindowPtr drawIt);
  32.  
  33. Boolean DoSelected(long val);
  34.  
  35. void InitAEStuff(void);
  36.  
  37. void DoHighLevel(EventRecord *AERecord);
  38. void DoDaCall(MenuHandle themenu, long theit);
  39.      OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  40.  
  41.      OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  42.  
  43.      OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  44.  
  45.      OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  46.  
  47.      OSErr AESimpleHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  48. pascal Boolean idleProc(EventRecord *eventIn, long *sleep, RgnHandle *mouseRgn);
  49. /* interaction menu items */
  50. #define kSelfInteractItem 1
  51. #define kLocalInteractItem 2
  52. #define kAllInteractItem 3
  53. short gInteractArray[4] = 
  54. {
  55.     nil, kAEInteractWithSelf, kAEInteractWithLocal, kAEInteractWithAll
  56. };
  57.  
  58.  
  59. #define kMBarID 128
  60. #define kAppleMenu 128
  61. #define kFileMenu 129
  62. #define kEditMenu 130
  63. #define kToolsMenu 131
  64. #define kResumeMask             1       /* bit of message field for resume vs. suspend */
  65. MenuHandle gAppleMenuHandle, gFileMenuHandle, gEditMenuHandle, gToolMenuHandle;
  66. Handle gMymenu;                                             /* my menu bar handle */
  67.  
  68. AEAddressDesc targetAddress;                                /* address of the person to get the data from */
  69.  
  70.  
  71. #define kSimpleEvent 'SIMP'
  72. #define kSimpleClass 'Simp'
  73. Boolean gQuit, gInBackground;
  74. EventRecord gERecord;
  75. WindowPtr myWindow;
  76. short gInteractNow = kSelfInteractItem;
  77. AEIdleUPP  gAEIdleUPP;
  78.  
  79. #ifdef powerc
  80.    QDGlobals    qd;
  81. #endif
  82.  
  83. main()
  84. {
  85.     WindowPtr twindow;
  86.     MaxApplZone();
  87.     InitGraf((Ptr)&qd.thePort);
  88.     InitFonts();
  89.     InitWindows();
  90.     InitMenus();
  91.     TEInit();
  92.     InitDialogs(nil);
  93.     InitCursor();
  94.     
  95.     InitAEStuff();
  96.     
  97.     gMymenu = GetNewMBar(kMBarID);
  98.     SetMenuBar(gMymenu);
  99.     gAppleMenuHandle = GetMenuHandle(kAppleMenu);
  100.     gFileMenuHandle = GetMenuHandle(kFileMenu);
  101.     gEditMenuHandle = GetMenuHandle(kEditMenu);
  102.     gToolMenuHandle = GetMenuHandle(kToolsMenu);
  103.     
  104.     AppendResMenu(gAppleMenuHandle, 'DRVR');
  105.     DrawMenuBar();
  106.     CheckItem(gToolMenuHandle, gInteractNow, true);
  107.     GetNewWindow(128, nil, (WindowPtr)-1);
  108.     
  109.     do {
  110.         WaitNextEvent(everyEvent, &gERecord, 30, nil);
  111.         switch (gERecord.what) {
  112.             
  113.             case nullEvent:
  114.                 /* no nul processing in this sample */
  115.                 break;
  116.             case updateEvt:
  117.                 DrawMain((WindowPtr)gERecord.message);      /* draw whatever window needs an update */
  118.                 break;
  119.             case mouseDown:
  120.                 /* first see where the hit was */
  121.                 switch (FindWindow(gERecord.where, &twindow)) {
  122.                     
  123.                     case inDesk:                            /* if they hit in desk, then the process manager */
  124.                         break;                              /* will switch us out, we don't need to do anything */
  125.                     case inMenuBar:
  126.                         DoSelected(MenuSelect(gERecord.where));
  127.                         break;
  128.                         
  129.                     case inSysWindow:
  130.                         /* pass to the system */
  131.                         SystemClick(&gERecord, twindow);
  132.                         break;
  133.                     case inContent:
  134.                         break;
  135.                     case inDrag:
  136.                         if (twindow == FrontWindow())
  137.                             DragWindow(twindow, gERecord.where, &qd.screenBits.bounds);
  138.                         break;
  139.                     case inGrow:
  140.                     case inGoAway:
  141.                         /* don't care */
  142.                         break;
  143.                         
  144.                 }
  145.             case mouseUp:
  146.                 /* don't care */
  147.                 break;
  148.                 /* same action for key or auto key */
  149.             case keyDown:
  150.             case autoKey:
  151.                 if (gERecord.modifiers & cmdKey)
  152.                     DoSelected(MenuKey(gERecord.message & charCodeMask));
  153.                 break;
  154.             case keyUp:
  155.                 /* don't care */
  156.                 break;
  157.             case diskEvt:
  158.                 /* I don't do anything special for disk events, this just passes them */
  159.                 /* to a function that checks for an error on the mount */
  160.                 DoDiskEvents(gERecord.message);
  161.                 break;
  162.             case activateEvt:
  163.                 /* Draws on a window activate.  Other activate/deactivate stuff is */
  164.                 /* handled in either the ChangePlane function (for normal shuffling ) */
  165.                 /* or in the suspend/resume handler for layer swaps */
  166.                 if (gERecord.modifiers & activeFlag)
  167.                     DrawMain((WindowPtr)gERecord.message);
  168.                 break;
  169.             case networkEvt:
  170.                 /* don't care */
  171.                 break;
  172.             case driverEvt:
  173.                 /* don't care */
  174.                 break;
  175.             case app4Evt:
  176.                 switch ((gERecord.message >> 24) & 0x0FF) {     /* high byte of message */
  177.                     case suspendResumeMessage:              /* suspend/resume is also an activate/deactivate */
  178.                         gInBackground = (gERecord.message & kResumeMask) == 0;
  179.                         break;
  180.                 }
  181.                 break;
  182.             default:
  183.                 break;
  184.                 /* This dispatches high level events (AppleEvents, for example) */
  185.                 /* to our dispatch routine.  This is NEW in the event loop for */
  186.                 /* System 7 */
  187.             case kHighLevelEvent:
  188.                 DoHighLevel(&gERecord);
  189.                 break;
  190.                 
  191.         }
  192.     } while (gQuit != true);
  193.     
  194.     
  195. }
  196.  
  197. /* DoDaCall opens the requested DA.  It's here as a seperate routine if you'd */
  198. /* like to perform some action or just know when a DA is opened in your */
  199. /* layer.  Can be handy to track memory problems when a DA is opened */
  200. /* with an Option-open */
  201. void DoDaCall(MenuHandle themenu, long theit)
  202. {
  203.     long qq;
  204.     char DAname[255];
  205.     GetMenuItemText(themenu, theit, &DAname);
  206.     qq = OpenDeskAcc(DAname);
  207. }
  208.  
  209. /* end DoDaCall */
  210.  
  211. /* DoDiskEvents just checks the error code from the disk mount, */
  212. /* and puts up the 'Format' dialog (through DIBadMount) if need be */
  213. /* You can do much more here if you care about what disks are */
  214. /* in the drive */
  215. void DoDiskEvents(long dinfo)                               /* hi word is error code, lo word is drive number */
  216. {
  217.     short hival, loval, tommy;
  218.     Point fredpoint =  {
  219.         40, 40
  220.     };
  221.     hival = HiWord(dinfo);
  222.     loval = LoWord(dinfo);
  223.     if (hival != noErr)                                     /* something happened */ {
  224.         tommy = DIBadMount(fredpoint, dinfo);
  225.     }
  226. }
  227.  
  228. void DrawMain(WindowPtr drawIt)
  229. {
  230.     BeginUpdate(drawIt);
  231.     SetPort(drawIt);
  232.     MoveTo(40, 70);
  233.     TextFace(bold);
  234.     TextSize(20);
  235.     DrawString("\pThis Does Nothing");
  236.     EndUpdate(drawIt);
  237. }
  238.  
  239. Boolean DoSelected(long val)
  240. {
  241.     short loval, hival;
  242.     Boolean temp = false;
  243.     loval = LoWord(val);
  244.     hival = HiWord(val);
  245.     
  246.     switch (hival) {                                        /* switch off the menu number selected */
  247.         case kAppleMenu:                                    /* Apple menu */
  248.             if (loval != 1) {                               /* if this was not About, it's a DA */
  249.                 DoDaCall(gAppleMenuHandle, loval);
  250.             } else {
  251.                 Alert(128, nil);                            /* do about box */
  252.             }
  253.             break;
  254.         case kFileMenu:                                     /* File menu */
  255.             gQuit = true;                                   /* only edit item */
  256.             break;
  257.         case kEditMenu:
  258.             /* edit menu junk */
  259.             /* don't care */
  260.             break;
  261.         case kToolsMenu:
  262.             if (loval != gInteractNow) {
  263.                 CheckItem(gToolMenuHandle, gInteractNow, false);
  264.                 CheckItem(gToolMenuHandle, loval, true);
  265.                 AESetInteractionAllowed(gInteractArray[loval]);
  266.                 gInteractNow = loval;
  267.             }
  268.     }
  269.     HiliteMenu(0);
  270. }
  271.  
  272. void InitAEStuff(void)
  273. {
  274.     OSErr aevtErr = noErr;
  275.     long aLong = 0;
  276.     Boolean gHasAppleEvents = false;
  277.     /* Check this machine for AppleEvents.  If they are not here (ie not 7.0)
  278.     *   then we exit */
  279.     gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &aLong) == noErr);
  280.     /* The following series of calls installs all our AppleEvent Handlers.
  281.     *   These handlers are added to the application event handler list that 
  282.     *   the AppleEvent manager maintains.  So, whenever an AppleEvent happens
  283.     *   and we call AEProcessEvent, the AppleEvent manager will check our
  284.     *   list of handlers and dispatch to it if there is one.
  285.     */
  286.     if (gHasAppleEvents) {
  287.             aevtErr =  AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, 
  288.                         NewAEEventHandlerProc(AEOpenHandler),0, false);
  289.                         if (aevtErr)  ExitToShell();
  290.  
  291.             aevtErr =  AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, 
  292.                         NewAEEventHandlerProc(AEOpenDocHandler),0, false);
  293.                         if (aevtErr)  ExitToShell();
  294.             
  295.             aevtErr = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, 
  296.                         NewAEEventHandlerProc(AEPrintHandler),0, false);
  297.                         if (aevtErr)  ExitToShell();
  298.            
  299.             aevtErr = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, 
  300.                         NewAEEventHandlerProc(AEQuitHandler),0, false);
  301.                         if (aevtErr)  ExitToShell();
  302.            
  303.             aevtErr = AEInstallEventHandler(kSimpleClass, kSimpleEvent, 
  304.                         NewAEEventHandlerProc(AESimpleHandler),0, false);
  305.                         if (aevtErr)  ExitToShell();
  306.                                 
  307.             /* create a UPP for the AppleEvent idle proc */
  308.             gAEIdleUPP = NewAEIdleProc(idleProc);
  309.  
  310.             }
  311.   else ExitToShell();
  312. }
  313.  
  314. /* end InitAEStuff */
  315.  
  316. void DoHighLevel(EventRecord *AERecord)
  317. {
  318.     
  319.     AEProcessAppleEvent(AERecord);
  320.     
  321. }
  322.  
  323. /* end DoHighLevel */
  324.  
  325. /* This is the standard Open Application event.  You'll get this as one of the (if not the ) */
  326. /* first events in your application.  So, we open up a blank document */
  327.      OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  328. {
  329. #pragma unused (messagein,reply,refIn)
  330.     /* we of course don't do anything here, since we're background only */
  331.     return(noErr);
  332. }
  333.  
  334. /* end AEOpenHandler */
  335.  
  336. /* Open Doc, opens our documents.  Remember, this can happen at application start AND */
  337. /* anytime else.  If your app is up and running and the user goes to the desktop, hilites one */
  338. /* of your files, and double-clicks or selects Open from the finder File menu this event */
  339. /* handler will get called. Which means you don't do any initialization of globals here, or */
  340. /* anything else except open then doc.  */
  341. /* SO-- Do NOT assume that you are at app start time in this */
  342. /* routine, or bad things will surely happen to you. */
  343.  
  344.      OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  345. {
  346. #pragma unused (reply, refIn)
  347.     /* we of course don't do anything here */
  348.     return(errAEEventNotHandled);                           /* we have no docs, so no odoc events should come to us */
  349.     
  350. }
  351.  
  352.      OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  353. {                                                           /* no printing handler in yet, so we'll ignore this */
  354.     /* the operation is functionally identical to the ODOC event, with the additon */
  355.     /* of calling your print routine.  */
  356. #pragma unused (reply,refIn)
  357.     /* we of course don't do anything here */
  358.     return(errAEEventNotHandled);                           /* we have no docs, so no odoc events should come to us */
  359. }
  360.  
  361. /* Standard Quit event handler, to handle a Quit event from the Finder, for example.  */
  362. /* ••••• DO NOT CALL EXITTOSHELL HERE ••••• or you will never have a happy life.  */
  363.      OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  364. {
  365. #pragma unused (messagein,refIn)
  366.     
  367.     /* prepQuit sets the Stop flag for us.  It does _NOT_ quit, you */
  368.     /* should NEVER quit from an AppleEvent handler.  Calling */
  369.     /* ExitToShell here would blow things up */
  370.     gQuit = true;
  371.     return(noErr);
  372. }
  373.  
  374. OSErr AESimpleHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  375. {
  376.     OSErr myErr = AEInteractWithUser(kAEDefaultTimeout, nil, gAEIdleUPP);
  377.     if (myErr != errAENoUserInteraction)
  378.         Alert(444, nil);
  379.     return(noErr);
  380. }
  381.  
  382. pascal Boolean idleProc(EventRecord *eventIn, long *sleep, RgnHandle *mouseRgn)
  383. {
  384.     switch (eventIn->what) {
  385.         case nullEvent:
  386.             /* no nul processing in this sample */
  387.             *sleep = 0;
  388.             mouseRgn = nil;
  389.             break;
  390.         case updateEvt:
  391.         case activateEvt:
  392.             DrawMain((WindowPtr)eventIn->message);          /* draw whatever window needs an update */
  393.             break;
  394.         case app4Evt:
  395.             switch ((gERecord.message >> 24) & 0x0FF) {     /* high byte of message */
  396.                 case suspendResumeMessage:                  /* suspend/resume is also an activate/deactivate */
  397.                     gInBackground = (gERecord.message & kResumeMask) == 0;
  398.                     break;
  399.             }
  400.             break;
  401.             
  402.             
  403.     }
  404.     return(false);                                          /* I'll wait forever */
  405. }
  406.